var Sunburst = function(zoomableJSON) {

var width = 900,
    height = 680,
    radius = Math.min(width, height) / 2,
    border_width = 25,
    border_padding = 12,
    svg_width = width + (border_width * 2),
    svg_height = height + (border_width * 4),
    cytobank_blue = "#AACEF2",
    dark_blue = "#305F8E";
    currentPopName = "";
    currentPopSize = "";

var x = d3.scale.linear()
    .range([0, 2 * Math.PI]);

var y = d3.scale.linear()
    .range([0, radius]);

var color = d3.scale.category20c();

var svg = d3.select("body").append("svg")
    .attr("width", svg_width)
    .attr("height", svg_height)
    .append("g")
    .attr("transform", "translate(" + (width - 40) / 2 + "," + ((height + 40) / 2 + 10) + ")");

d3.select("svg").append('rect')
    .attr({
    x: border_padding,
    y: border_padding,
    width: width - 100,
    height: 734
})
    .style({
    stroke: cytobank_blue,
        "stroke-width": border_width,
    fill: "none"
});

var partition = d3.layout.partition()
    .value(function (d) {
    return d.size;
});

var arc = d3.svg.arc()
    .startAngle(function (d) {
    return Math.max(0, Math.min(2 * Math.PI, x(d.x)));
})
    .endAngle(function (d) {
    return Math.max(0, Math.min(2 * Math.PI, x(d.x + d.dx)));
})
    .innerRadius(function (d) {
    return Math.max(0, y(d.y));
})
    .outerRadius(function (d) {
    return Math.max(0, y(d.y + d.dy));
});

var g = svg.selectAll("g")
    .data(partition.nodes(zoomableJSON))
    .enter().append("g");

var path = g.append("path")
    .attr("d", arc)
    .attr("size", function (d) {
        var $d = $(d);
        var d_size = $d.attr('size');
        var d_childsize = $d.attr('child-size');
        if (d_size !== undefined) {
            return d_size;
        } else {
            return d_childsize;
        }
    })
    .style("fill", function (d) {
        return color((d.children ? d : d.parent).name);
    })
    .on("click", click);

var text = g.append("text")
    .attr("transform", function (d) {
        return "rotate(" + computeTextRotation(d) + ")";
    })
    .attr("x", function (d) {
        return y(d.y);
    })
    .attr("dx", "6") // margin
    .attr("dy", ".35em") // vertical-align
    .style('pointer-events', 'none')
    .text(function (d) {
        return d.name;
    }).on('click', function() {
        var $path = d3.select($(this).parent().find('path'));
        $path.on('click')();
    })

function click(d) {

    currentPopName = d.name;
    var size = d.size;
    if (size === undefined) {
        size = d['child-size'];
    }
    if (size !== undefined) {
        currentPopSize = "# cells: " + size.toString();
    } else {
        currentPopSize = "";
    }

    // fade out all text elements
    text.transition().attr("opacity", 0);

    path.transition()
        .duration(750)
        .attrTween("d", arcTween(d))
        .each("end", function (e, i) {
        // check if the animated element's data e lies within the visible angle span given in d
        if (e.x >= d.x && e.x < (d.x + d.dx)) {
            // get a selection of the associated text element
            var arcText = d3.select(this.parentNode).select("text");
            // fade in the text element and recalculate positions
            arcText.transition().duration(750)
                .attr("opacity", 1)
                .attr("transform", function () {
                return "rotate(" + computeTextRotation(e) + ")"
            })
                .attr("x", function (d) {
                return y(d.y);
            });
        }
    });
}

d3.select(self.frameElement).style("height", height + "px");

// Interpolate the scales!
function arcTween(d) {
    var xd = d3.interpolate(x.domain(), [d.x, d.x + d.dx]),
        yd = d3.interpolate(y.domain(), [d.y, 1]),
        yr = d3.interpolate(y.range(), [d.y ? 20 : 0, radius]);
    return function (d, i) {
        return i ? function (t) {
            return arc(d);
        } : function (t) {
            x.domain(xd(t));
            y.domain(yd(t)).range(yr(t));
            return arc(d);
        };
    };
}

function computeTextRotation(d) {
    return (x(d.x + d.dx / 2) - Math.PI / 2) / Math.PI * 180;
}


    var $gs = $('g > g');

    d3.select("svg").append('text')
        .text('')
        .attr('id', 'population-text')
        .attr('x', 500)
        .attr('y', 60)
        .style({
        "font-size": "2em",
            "fill": dark_blue
    });
    d3.select("svg").append('text')
        .text('')
        .attr('id', 'size-text')
        .attr('x', 500)
        .attr('y', 100)
        .style({
        "font-size": "2em",
            "text-anchor": "right",
            "fill": dark_blue
    });

    var $num_cells = d3.select('#size-text');
    var $pop_text = d3.select('#population-text');
    var mousing_over = false;
    $gs.on('mouseenter', function() {
           mousing_over = true;
           var $this = $(this);
           $num_cells.text("# cells: " + $this.find('path').attr('size').toString());
           $pop_text.text($this.find('text').text());
    }).on('mouseleave', function() {
           mousing_over = false;
           setTimeout(function() {
                   if (!mousing_over) {
                           $num_cells.text(currentPopSize);
                           $pop_text.text(currentPopName);
                   }
           }, 700)
    });
};
